package main

import (
	"container/heap"
	"fmt"
)

type MultiValue struct {
	v1 int64
	v2 int64
}

type MultiValueHeap []*MultiValue

func (m MultiValueHeap) Len() int {
	return len(m)
}

func (m MultiValueHeap) Swap(i, j int) {
	m[i], m[j] = m[j], m[i]
}

func (m *MultiValueHeap) Push(x any) {
	*m = append(*m, x.(*MultiValue))
}

func (m *MultiValueHeap) Pop() any {
	old := *m
	n := len(old)
	x := old[n-1]
	*m = old[0 : n-1]
	return x
}

type byV1 struct {
	MultiValueHeap
}

func (b byV1) Less(i, j int) bool {
	return b.MultiValueHeap[i].v1 < b.MultiValueHeap[j].v1
}

type byV2 struct {
	MultiValueHeap
}

func (b byV2) Less(i, j int) bool {
	return b.MultiValueHeap[i].v2 < b.MultiValueHeap[j].v2
}

func main() {
	h1 := &byV1{MultiValueHeap: MultiValueHeap{}}
	h2 := &byV2{MultiValueHeap: MultiValueHeap{}}
	heap.Init(h1)
	heap.Init(h2)

	item1 := &MultiValue{v1: 5, v2: 3}
	item2 := &MultiValue{v1: 4, v2: 4}
	item3 := &MultiValue{v1: 3, v2: 2}
	item4 := &MultiValue{v1: 2, v2: 1}
	item5 := &MultiValue{v1: 1, v2: 5}
	heap.Push(h1, item1)
	heap.Push(h2, item1)
	heap.Push(h1, item2)
	heap.Push(h2, item2)
	heap.Push(h1, item3)
	heap.Push(h2, item3)
	heap.Push(h1, item4)
	heap.Push(h2, item4)
	heap.Push(h1, item5)
	heap.Push(h2, item5)

	println("h1")
	for h1.Len() > 0 {
		fmt.Printf("%d ", heap.Pop(h1))
	}
	println("\nh2")
	for h2.Len() > 0 {
		fmt.Printf("%d ", heap.Pop(h2))
	}
}
